package resilienceManager.qmul.gemom;



import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.Enumeration;
import java.util.Vector;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import cbr.resilienceManager.qmul.gemom.CbrData;



/**
 * the class for the overlayer manager
 * calculate the individual, Social 
 * 
 * COPYRIGHT DISCLAIMER
 * Synopsis: All the source codes presented in this document are intellectual
 * properties of Queen Mary, University of London.
 * 
 * @year 2010
 * @author Peng Jiang, John Bigham, Jiayi Wu Jinfu Wang------------QMUL
 * @version 1.0 
 */


public class NSPartitioner extends JFrame {

	JTextField textField = new JTextField();

	JScrollPane scrollPane = new JScrollPane();

	static JList jlist;

	static JTree tree;

	Renderer renderer = new Renderer();

	File file;

	DefaultTreeModel[] Itemmodel= new DefaultTreeModel[100];

	int Item_num=0;

	NSitem[] items;
	
	Gbroker[] gblist;
	
	int bgID;
	
	// used for the case based reasoning
	public CbrData cd;



	public NSPartitioner(CbrData cbrDa) {
		
		

		super("Namespace Set Partitioner");
		
		//setup the 
		this.cd=cbrDa;

		DefaultMutableTreeNode top = new DefaultMutableTreeNode("root");
		tree = new JTree(top);

		tree.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent event) {
				if (((event.getModifiers() & InputEvent.BUTTON3_MASK) != 0)
						&& (tree.getSelectionCount() > 0)) {
					showMenu(event.getX(), event.getY());
				}
			}
		});


		getContentPane().setLayout(new BorderLayout());
		tree.setCellRenderer(renderer);
		tree.addTreeSelectionListener(new TreeHandler());
		scrollPane.getViewport().add(tree);
		getContentPane().add("Center", scrollPane);
		getContentPane().add("North", textField);

		// set up the button panel
		JPanel panel = new JPanel(new GridLayout(2, 2));

		JButton divButton = new JButton("Open");
		divButton.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(ActionEvent event) {
				//divideSelectedItems(true,null);
				setupTree();
			}
		});

		JButton autButton = new JButton("Auto");
		autButton.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(ActionEvent event) {
				DefaultTreeModel model = (DefaultTreeModel) (tree.getModel());
				DefaultMutableTreeNode root=(DefaultMutableTreeNode)model.getRoot();
				auto(root,0);

			}
		});

		JButton resetButton = new JButton("Reset");
		resetButton.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(ActionEvent event) {
				reset();
			}
		});

		JButton saveButton = new JButton("Save");
		saveButton.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(ActionEvent event) {
				saving();
				
				NSitem[] t=Datasaver.getItems(cd.getTableID());
				//AuctionFrame af=new AuctionFrame(items, gblist, bgID);
				AuctionFrame af=new AuctionFrame(t, gblist,cd,false);


			}
		});

		panel.add(divButton);
		panel.add(autButton);
		panel.add(resetButton);
		panel.add(saveButton);

		getContentPane().add("South", panel);

		// set up the list panel

		String labels[] = { "Root    " };

		jlist = new JList(labels);

		jlist.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);


		ListSelectionListener listselection = new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent listSelectionEvent) {

				boolean adjust = listSelectionEvent.getValueIsAdjusting();
				if (!adjust) {
					JList list = (JList) listSelectionEvent.getSource();
					int selections = list.getSelectedIndex();
					showTree(selections);


				}
			}
		};

		jlist.addListSelectionListener(listselection);


		JScrollPane scrollPane1 = new JScrollPane(jlist);

		getContentPane().add("West", scrollPane1);
		
		
		preSetup(cd.getTableID());



		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

		setSize(600, 600);
		setVisible(true);
	}

	/**
	 * the jlist selection function
	 * 
	 * when you select the item , show the tree structure
	 * */
	protected void showTree(int treeid)
	{

		DefaultMutableTreeNode top =(DefaultMutableTreeNode)Itemmodel[treeid].getRoot();


		DefaultTreeModel tmodel=new DefaultTreeModel(top);

		tree.setModel(tmodel);

		expandAll(tree,new TreePath(top),true);


	}

	/**
	 * the pop menu for the division and source import 
	 * 
	 * */
	protected void showMenu(int x, int y) {
		JPopupMenu popup = new JPopupMenu();
		JMenuItem mi = new JMenuItem("Divide");
		JMenuItem si = new JMenuItem("Source");
		TreePath path = tree.getSelectionPath();
		Object node = path.getLastPathComponent();
		if (node == tree.getModel().getRoot()) {
			mi.setEnabled(false);
		}
		popup.add(mi);
		popup.add(si);
		mi.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(ActionEvent event) {
				divideSelectedItems(true,null);
			}
		});

		si.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(ActionEvent event) {
				setupTree();
			}
		});

		popup.show(tree, x, y);

	}
	public void divideSelectedItems(boolean selected, DefaultMutableTreeNode removenode) {
		DefaultMutableTreeNode node;
		DefaultTreeModel model = (DefaultTreeModel) (tree.getModel());
		if(selected)
		{
		TreePath path = tree.getSelectionPath();
		node = (DefaultMutableTreeNode) (path.getLastPathComponent());
		}else
		{
			node=removenode;
		}
		model.removeNodeFromParent(node);

		Itemmodel[0]=new DefaultTreeModel((TreeNode) model.getRoot());
		Item_num=Item_num+1;
		Itemmodel[Item_num]= new DefaultTreeModel(node);


		DefaultListModel listmodel= new DefaultListModel();
		String ni;

		for(int i=1; i<Item_num+2; i++)
		{
			ni=new String("Item"+i);
			listmodel.addElement(ni);

		}


		jlist.setModel(listmodel);

		this.repaint();

	}




	/**
	 * import the information of Gbroker and 
	 * @return 
	 * */	
	
	public void SetGB(Gbroker[] gb, int bg)
	{
		this.gblist=gb;
		
		this.bgID=bg;
	}


	/**
	 * Import the name space from the data base
	 * build a tree node
	 * @return 
	 * */
	private boolean setupTree()
	{

		DefaultMutableTreeNode top;

		JFileChooser fc=new JFileChooser();

		XMLfilter filter = new XMLfilter();

		fc.setFileFilter(filter);

		int returnVal = fc.showOpenDialog(this);

		if (returnVal == JFileChooser.APPROVE_OPTION) {
			file = fc.getSelectedFile();

			nsParser nsp=new nsParser(file,cd);
			nsp.buildNS();


			top=nsp.getSAXTree();
			
			DefaultTreeModel tmodel=new DefaultTreeModel(top);

			tree.setModel(tmodel);

			//DefaultMutableTreeNode root=(DefaultMutableTreeNode) tree.getModel().getRoot(); 
			//root.removeAllChildren();
			//addAll(root,top);
			expandAll(tree,new TreePath(top),true);
			tree.getParent().repaint();

			Itemmodel[0]=new DefaultTreeModel((DefaultMutableTreeNode)top.clone());
			Item_num=0;

			return true;
		}
		else
		{
			return false;
		}


	}
	
	
	/**
	 * use for the pre set namespace
	 * load the namespace set before you chose the 
	 * **/
	
	private boolean preSetup(int id){
		
		DefaultMutableTreeNode top;
		
		//String filename= "C:\\Users\\pengj\\Documents\\ns"+id+".xml";
		String filename= "images\\ns"+id+".xml";
		file = new File(filename);
	    
		if(file.exists())
		{
			nsParser nsp=new nsParser(file,cd);
			nsp.buildNS();


			top=nsp.getSAXTree();
			
			DefaultTreeModel tmodel=new DefaultTreeModel(top);

			tree.setModel(tmodel);

			//DefaultMutableTreeNode root=(DefaultMutableTreeNode) tree.getModel().getRoot(); 
			//root.removeAllChildren();
			//addAll(root,top);
			expandAll(tree,new TreePath(top),true);
			tree.getParent().repaint();

			Itemmodel[0]=new DefaultTreeModel((DefaultMutableTreeNode)top.clone());
			Item_num=0;
			
			return true;
		}
		else
		{
			return false;
		}

		
		
	}

	//save all the divide item to the NSitem list
	private void saving(){

		items=new NSitem[Item_num+1];

		for(int i=0; i<Item_num+1; i++)
		{
			DefaultTreeModel dt=Itemmodel[i];
			items[i]=new NSitem(i);

			DefaultMutableTreeNode root=(DefaultMutableTreeNode)dt.getRoot();
			// save the fisrt root name space 
			int nsid=Datasaver.findID(root.toString(),cd.getTableID());
			
			items[i].addNS(nsid);
			
			// save the rest of the name space
			visitAll(items[i],root);			
		}
		
		Datasaver.saveItems(items,cd.getTableID());
	}

	private void visitAll(final NSitem nst, DefaultMutableTreeNode node)
	{
		if (node.getChildCount() >= 0) {
			for (Enumeration e=node.children(); e.hasMoreElements(); ) {
				DefaultMutableTreeNode n = (DefaultMutableTreeNode)e.nextElement();
				int nsid=Datasaver.findID(n.toString(),cd.getTableID());
				nst.addNS((Integer)nsid);
				visitAll(nst,n);
			}
		}
	}

	// auto divide the namespace tree
	
	private int level=2;
	private void auto(DefaultMutableTreeNode node,int le){
		
		while(node.getChildCount() >= 0)
		{
			for (Enumeration e=node.children(); e.hasMoreElements(); ) {
				DefaultMutableTreeNode n = (DefaultMutableTreeNode)e.nextElement();
				if(le==level)
				{
					divideSelectedItems(false,n);
				}else
				{
					le=le+1;
					auto(n,le);
				}
			}
		}
		
		

	}

	private void reset(){
		nsParser nsp=new nsParser(file, cd);

		DefaultMutableTreeNode top=nsp.getSAXTree();


		Itemmodel[0]=new DefaultTreeModel(top);

		Item_num=0;

		tree.setModel(Itemmodel[0]);

		DefaultListModel listmodel= new DefaultListModel();

		listmodel.addElement("Root");

		jlist.setModel(listmodel);

		expandAll(tree,new TreePath(top),true);
	}

	private void expandAll(JTree tree, TreePath parent, boolean expand) {
		// Traverse children
		DefaultMutableTreeNode node = (DefaultMutableTreeNode)parent.getLastPathComponent();
		if (node.getChildCount() >= 0) {
			for (Enumeration e=node.children(); e.hasMoreElements(); ) {
				DefaultMutableTreeNode n = (DefaultMutableTreeNode)e.nextElement();
				TreePath path = parent.pathByAddingChild(n);
				expandAll(tree, path, expand);
			}
		}

		// Expansion or collapse must be done bottom-up
		if (expand) {
			tree.expandPath(parent);
		} else {
			tree.collapsePath(parent);
		}
	}

	private void addAll(final DefaultMutableTreeNode root, final DefaultMutableTreeNode anode)
	{
		if (anode.getChildCount() >= 0) {
			for(Enumeration e=anode.children(); e.hasMoreElements();){
				DefaultMutableTreeNode n = (DefaultMutableTreeNode)e.nextElement();
				//addAll(root,n);
				root.add(n);
			}
		}
		else{
			//root.add(anode);
		}
	}

	private class TreeHandler implements TreeSelectionListener {
		public void valueChanged(TreeSelectionEvent e) {
			TreePath path = e.getPath();
			//String text = path.getPathComponent(path.getPathCount() - 1).toString();
			String text=Datasaver.pathtransfer(path.toString());
			textField.setText(text);
		}
	}


}


